package com.lngsyz.file.biz.service;

import java.nio.file.FileStore;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.lngsyz.file.entity.source1.SystemFileupload;
import com.lngsyz.file.exception.RequestSystemException;
import com.lngsyz.file.service.source1.SystemFileuploadService;

@Service
public class TransFileService {
    
	@Autowired
	SystemFileuploadService systemFileuploadService;

	/**
     * 按日期取指定日期的数据
     * 将数据按线程数量拆分成多个线程
     */
    public void transFile(String startDate, int jobCount) {
    	try {
			checkDiskSpace();
		} catch (Exception e1) {
			System.out.println("/data磁盘空间获取失败");
		}
    	// 获取指定条数的数据
    	List<SystemFileupload> sfs = new ArrayList<SystemFileupload>();
    	try {
    		sfs = systemFileuploadService.findByDate(startDate);
    		System.out.println("查询到的数据：" + sfs.size() + "条");
    	} catch(Exception e) {
    		System.out.println("前置机查询网络断了~~~");
    	}
    	int total = 10000;
    	try {
    		System.out.println("分页：查询到的数据：" + sfs.size() + "条， 需要分页" + Math.ceil((double) sfs.size() / total) + "次");
    		// 分页，每次取10000条
    		for(int page = 1; page <= Math.ceil((double) sfs.size() / total); page++) {
    			// sfs分页，取total的数据
    			int rowStart = total * (page - 1);
    			List<SystemFileupload> pageList= (List<SystemFileupload>) sfs.stream().skip(rowStart).limit(total).collect(Collectors.toList());
    			// 执行
    			ExecutorService pool = Executors.newFixedThreadPool(100);
        		int trCount = 200;
        		List<Future> futureList = new ArrayList<Future>();
        		// 分发线程
        		for(int tr = 1; tr <= Math.ceil((double) pageList.size() / trCount); tr++) {
        			// 线程内分页，取trCount的数据
        			int trStart = trCount * (tr - 1);
        			List<SystemFileupload> trList= (List<SystemFileupload>) pageList.stream().skip(trStart).limit(trCount).collect(Collectors.toList());
        			Callable c = new MyCompareCallableUpdate(trList,total);
    				Future f = pool.submit(c);
    				futureList.add(f);
        		}
        		System.out.println("第" + page + "页" + futureList.size() + "个线程");
        		// 检查线程完成情况
        		if(pageList != null && pageList.size() > 0) {
        			System.out.println("每个线程" + trCount + "条数据，子线程数量：" + futureList.size());
        			int success = 0;
        			for(Future future : futureList){
        				future.get();
        			}
        		}
    		}
    	} catch(Exception e) {
    		e.printStackTrace();
    	}
    }
    
    class MyCompareCallableUpdate implements Callable{
    	private List<SystemFileupload> sfs;
    	private int index;
    	
    	MyCompareCallableUpdate(List<SystemFileupload> dataList){
    		this.sfs = dataList;
    	}
    	MyCompareCallableUpdate(List<SystemFileupload> dataList,int index){
    		this.sfs = dataList;
    		this.index = index;
    	}
    	@Override
    	public Object call() throws Exception {
    		// 循环遍历
    		int i = 0;
    		for(SystemFileupload sf : sfs) {
    			try {
    				if(StringUtils.startsWith(sf.getFilepath(), "/nfs/")) {
    					Path sourcePath = Paths.get(sf.getFilepath());
    					Path targetPath = Paths.get(StringUtils.replace(sf.getFilepath(), "/nfs/", "/data/"));
    					saveFile(sourcePath, targetPath);
//    					callBack(sf);
    					i++;
    				}
    			} catch(Exception e) {
    				
    			}
    		}
    		return i;
    	}
    }
    
    private void callBack(SystemFileupload sf) throws Exception {
    	systemFileuploadService.updateSource(sf.getId());
    }
    
    private void saveFile(Path sourcePath, Path targetPath) throws Exception {
    	try {
            // 创建目标目录（如果不存在）
            Files.createDirectories(targetPath.getParent());
            // 复制文件到目标位置
            Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
            System.out.print(".");
        } catch (Exception e) {
            System.err.println("文件复制失败: " + e.getMessage());
        }
	}
    
    public String checkDiskSpace(String pathStr) throws Exception {
    	String rtn = "";
    	Path path = Paths.get(pathStr);
    	try {
            // 获取文件存储对象
            FileStore fileStore = FileSystems.getDefault().getFileStores().iterator().next();
            for (FileStore store : FileSystems.getDefault().getFileStores()) {
                if (store.toString().contains(path.toString())) {
                    fileStore = store;
                    break;
                }
            }

            // 获取总空间、可用空间和未分配空间
            long totalSpace = fileStore.getTotalSpace();
            long usableSpace = fileStore.getUsableSpace();

            rtn = "总空间: " + totalSpace / (1024 * 1024 * 1024) + " GB" + "\t 可用空间: " + usableSpace / (1024 * 1024 * 1024) + " GB";
            System.out.println(rtn);
        } catch (Exception e) {
        	throw new RequestSystemException("磁盘空间查询失败");
        }
    	return rtn;
    }
    
    public String checkDiskSpace() throws Exception {
    	String rtn = "";
    	Path path = Paths.get("/data");
    	try {
            // 获取文件存储对象
            FileStore fileStore = FileSystems.getDefault().getFileStores().iterator().next();
            for (FileStore store : FileSystems.getDefault().getFileStores()) {
            	// System.out.println(store.toString());
                if (store.toString().contains(path.toString())) {
                    fileStore = store;
                    break;
                }
            }

            // 获取总空间、可用空间和未分配空间
            long totalSpace = fileStore.getTotalSpace();
            long usableSpace = fileStore.getUsableSpace();

            rtn = "总空间: " + totalSpace / (1024 * 1024 * 1024) + " GB" + "\t 可用空间: " + usableSpace / (1024 * 1024 * 1024) + " GB";
            System.out.println(rtn);
        } catch (Exception e) {
        	throw new RequestSystemException("磁盘空间查询失败");
        }
    	return rtn;
    }
    
    public static void main(String[] args) {
    	System.out.println(Math.ceil(126 / 10000));
    }
}
